package cn.qdhlm.collectservice.core.component.analyse;


import cn.qdhlm.collectservice.common.Constant;
import cn.qdhlm.collectservice.common.util.CodeUtil;
import cn.qdhlm.collectservice.common.util.ComUtil;



import cn.qdhlm.collectservice.service.UtilityService;
import io.netty.buffer.ByteBuf;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

/**
 * @Name: AnyAfn0d
 * @Description: 请求2类数据（AFN=0DH）
 * @Author: jiangcs
 */
@Log4j2
@Component
public class AnyAfn0d {

    @Autowired
    private UtilityService utilityService;

    public boolean execute(int da, int dt, int sn, String collectorNo, ByteBuf byteBuf) throws Exception {


        boolean executeFlag = false;

        // 采集时间
        String year = CodeUtil.byteToHexString(byteBuf.readByte()) + CodeUtil.byteToHexString(byteBuf.readByte());
        String month = CodeUtil.byteToHexString(byteBuf.readByte());
        String day = CodeUtil.byteToHexString(byteBuf.readByte());
        String hour = CodeUtil.byteToHexString(byteBuf.readByte());
        String minute = CodeUtil.byteToHexString(byteBuf.readByte());
        String collectTime = year + "-" + month + "-" + day + " " + hour + ":" + minute;



        // F15:读最近一次历史数据（单个）|| F22:读单个时间历史数据
        if ((da == Constant.DA_0 && dt == Constant.DT_16385) || (da == Constant.DA_0 && dt == Constant.DT_8194)) {
            processData(byteBuf, collectorNo, collectTime);

            // 更新命令结果状态
            Map<String, Object> resultMap = new HashMap<>(2);
            resultMap.put("statusCode", Constant.SYMBOL_00);
            resultMap.put("collectTime", collectTime);
//            utilityService.updateCommandResultStatus("terminal", collectorNo.getCollectorNo(), sn, resultMap, 2);

            executeFlag = true;
        }
        // F17:读最近一次历史数据（所有） || F24:读所有某时间历史数据
        else if ((da == Constant.DA_0 && dt == Constant.DT_258) || (da == Constant.DA_0 && dt == Constant.DT_32770)) {
            while (byteBuf.readableBytes() > Constant.BYTE_LENGTH_MIN_PACKAGE) {
                processData(byteBuf, collectorNo, collectTime);
            }

            // 更新命令结果状态
            Map<String, Object> resultMap = new HashMap<>(2);
            resultMap.put("statusCode", Constant.SYMBOL_00);
            resultMap.put("collectTime", collectTime);
//            utilityService.updateCommandResultStatus("collector", collectorNo.getCollectorNo(), sn, resultMap, 2);

            executeFlag = true;
        } else {
            log.error("execute da[{}], dt[{}] match fail", da, dt);
        }

        return executeFlag;
    }

    private void processData(ByteBuf byteBuf, String collectorNo, String collectTime) {
        // 终端编号
        StringBuilder sbTerminalNo = new StringBuilder();
        for (int i = 0; i < Constant.BYTE_LENGTH_TERMINAL_NO; i++) {
            String asciiStr = CodeUtil.byteToHexString(byteBuf.readByte());
            if (Constant.SYMBOL_00.equals(asciiStr)) {
                // 跳过剩余字节
                byteBuf.skipBytes(Constant.BYTE_LENGTH_TERMINAL_NO - i - 1);
                break;
            }
            sbTerminalNo.append(CodeUtil.hexStringToAsciiString(asciiStr));
        }
        String terminalNo = sbTerminalNo.toString();


            log.info("process data: terminalNo[{}] start", terminalNo);

            Map<String, Object> varMap = processVarData(byteBuf);
            if (varMap != null) {
                // 采集状态：最低位为0-成功；为1-失败
                int collectStatus = byteBuf.readByte() & 1;

                String terminalState = "", panelState = "";


                // 数据存储至mongodb
                utilityService.sendTerminalData(false, terminalNo,collectorNo, varMap, collectStatus, terminalState, panelState, collectTime);

                log.info("process data: terminalNo[{}] end", terminalNo);

                return;
            }

            log.error("process data: varMap is null");

    }

    /**
     * 处理 变量数据
     *
     * @param byteBuf
     * @return
     */
    private Map<String, Object> processVarData(ByteBuf byteBuf) {
        // 变量个数
        int varNum = byteBuf.readByte();
        if (varNum > 0) {
            String varType, year, month, day, hour, minute, second;
            Map<String, Object> varMap = new HashMap<>(15);
            for (int i = 0; i < varNum; i++) {
                varType = ComUtil.fillZeroLeft(byteBuf.readByte(), 2);
                if ("02".equals(varType)) {
                    varMap.put(varType, byteBuf.readIntLE());
                } else if ("15".equals(varType) || "20".equals(varType)) {
                    year = CodeUtil.byteToHexString(byteBuf.readByte()) + CodeUtil.byteToHexString(byteBuf.readByte());
                    month = CodeUtil.byteToHexString(byteBuf.readByte());
                    day = CodeUtil.byteToHexString(byteBuf.readByte());
                    hour = CodeUtil.byteToHexString(byteBuf.readByte());
                    minute = CodeUtil.byteToHexString(byteBuf.readByte());
                    second = CodeUtil.byteToHexString(byteBuf.readByte());
                    varMap.put(varType, year + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + second);
                } else {
                    varMap.put(varType, ComUtil.formatScale(byteBuf.readFloatLE() * 1.0, 4));
                }

                log.info("process varData: varType[{}] => {}", varType, varMap.get(varType));
            }
            return varMap;
        }

        log.error("process varData: varNum <= 0");
        return null;
    }
}
